package qa.tests;

import static java.util.ResourceBundle.getBundle;
import static qa.tests.TestTestPluginMojo.PATH_WERE_OUTPUT_IS;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;

/**
 * Generates a report containing information about the quality of the tests in the project.
 * 
 * @goal report
 */
public class TestTestPluginInReport extends AbstractMavenReport {

    private static final String OUTPUT_NAME = "assert-counter-maven-report";

    static final String BUNDLE_FILE = "count-asserts";

    /**
     * Directory containing the build files.
     * 
     * @parameter expression="${project.build.directory}"
     * @required
     * @readonly
     */
    private File buildDirectory;

    /**
     * <i>Maven Internal</i>: The Project descriptor.
     * 
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * <i>Maven Internal</i>: The Doxia Site Renderer.
     * 
     * @component
     */
    private Renderer siteRenderer;

    /**
     * Directory where report will be generated to.
     * 
     * @parameter expression="${project.reporting.outputDirectory}"
     * @required
     * @readonly
     */
    private String outputDirectory;

    /**
     * <i>Maven Internal</i>: List of artifacts for the plugin.
     * 
     * @parameter expression="${plugin.artifacts}"
     * @required
     * @readonly
     */
    private List<Artifact> pluginArtifacts;

    @Override
    protected void executeReport(Locale locale) throws MavenReportException {

        ClassLoader original = Thread.currentThread().getContextClassLoader();
        List<URL> urls = new ArrayList<URL>();
        try {
            List<String> elements = project.getTestClasspathElements();
            for (String element : elements) {
                URL url = new File(element).toURL();
                urls.add(url);
            }
            for (Artifact artifact : pluginArtifacts) {
                URL url = artifact.getFile().toURL();
                urls.add(url);
            }

        } catch (DependencyResolutionRequiredException e) {
            throw new MavenReportException("unable to add testclasspath", e);
        } catch (MalformedURLException e) {
            throw new MavenReportException("unable to add testclasspath", e);
        }

        URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), original);
        try {
            Thread.currentThread().setContextClassLoader(classLoader);
            new TestTestReportRenderer(getSink(), locale, new File(buildDirectory, PATH_WERE_OUTPUT_IS)).render();
        } finally {
            Thread.currentThread().setContextClassLoader(original);
        }
    }

    @Override
    protected String getOutputDirectory() {
        return outputDirectory;
    }

    @Override
    protected MavenProject getProject() {
        return project;
    }

    @Override
    protected Renderer getSiteRenderer() {
        return siteRenderer;
    }

    public String getDescription(Locale locale) {
        return getBundle(BUNDLE_FILE, locale).getString("description");
    }

    public String getName(Locale locale) {
        return getBundle(BUNDLE_FILE, locale).getString("name");
    }

    public String getOutputName() {
        return OUTPUT_NAME;
    }

    @Override
    public boolean canGenerateReport() {
        return super.canGenerateReport();
    }

}
